package com.jessechanrui.template.common.template.auth.application.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jessechanrui.template.common.template.auth.application.dto.req.UpdateUserPasswordRequest;
import com.jessechanrui.template.common.template.auth.application.service.UserService;
import com.jessechanrui.template.common.template.auth.common.AuthorizationSupport;
import com.jessechanrui.template.common.template.auth.domain.User;
import com.jessechanrui.template.common.template.auth.domain.support.repository.UserRepository;
import com.jessechanrui.template.common.template.auth.exception.AuthCenterException;
import com.jessechanrui.template.common.template.auth.exception.UserException;
import com.jessechanrui.template.common.template.auth.infrastructure.feign.AuthCenterFegin;
import com.jessechanrui.template.common.template.auth.infrastructure.feign.authcenter.AuthCenterUser;
import com.jessechanrui.template.common.template.auth.infrastructure.feign.authcenter.UserDetailResponse;
import com.jessechanrui.template.common.template.auth.infrastructure.feign.authcenter.UsersResponse;
import com.jessechanrui.template.core.entity.BasePageRequest;
import com.jessechanrui.template.core.util.DES3Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author chenrui
 * @version 1.0
 * @description UserServiceImpl
 * @date 2025/4/24
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private AuthCenterFegin authCenterFegin;

    @Override
    public User detail(String userName) {
        User user = userRepository.findByUserName(userName);
        if (ObjectUtil.isNull(user)) {
            throw new UserException("用户[" + userName + "]不存在，请在用户表中进行配置");
        }
        return user;
    }

    @Override
    public IPage<User> listByPage(BasePageRequest request) {
        return userRepository.listByPage(request);
    }

    @Override
    public void modify(User user) {
        if (StrUtil.isNotBlank(user.getGerritUserName())) {
            User gerritUserNameUser = userRepository.findByGerritUserName(user.getGerritUserName());
            if (gerritUserNameUser != null && !Objects.equals(gerritUserNameUser.getId(), user.getId())
                    && gerritUserNameUser.getGerritUserName().equals(user.getGerritUserName())) {
                throw new UserException("Gerrit用户名[" + user.getGerritUserName()
                        + "]已在用户[" + gerritUserNameUser.getUserName() + "]中配置，请勿重复配置");
            }
        }
        userRepository.updateUser(user);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updatePassword(UpdateUserPasswordRequest request) {
        UserDetailResponse response = authCenterFegin.modifyPassword(AuthorizationSupport.getCurrentUserToken(), request);
        if (!response.isSuccess()) {
            throw new AuthCenterException("认证中心修改密码失败，请稍后重试");
        }
        String currentUserName = AuthorizationSupport.getCurrentUserName();
        User user = userRepository.findByUserName(currentUserName);
        try {
            String secretKey = DES3Util.encode(request.getPassword1());
            user.setUserPassword(secretKey);
        } catch (Exception e) {
            throw new UserException("修改密码失败，" + e.getMessage());
        }
        userRepository.updateUser(user);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void synchronous() {
        UsersResponse response = authCenterFegin.users(AuthorizationSupport.getCurrentUserToken());
        if (!response.isSuccess()) {
            throw new AuthCenterException("认证中心用户获取失败，请稍后重试");
        }

        List<AuthCenterUser> authCenterUsers = response.getContent();
        //认证中心无用户数据，暂不处理
        if (CollectionUtil.isEmpty(authCenterUsers)) {
            return;
        }
        List<String> authCenterUserIds = authCenterUsers.stream().map(AuthCenterUser::getId).toList();
        Map<String, AuthCenterUser> authCenterUsersMap = authCenterUsers.stream().collect(Collectors.toMap(AuthCenterUser::getId, user -> user));
        List<User> existUsers = userRepository.list();
        Map<String, User> existUsersMap = existUsers.stream().collect(Collectors.toMap(User::getUserId, user -> user));

        List<String> existUserIds = existUsers.stream().map(User::getUserId).toList();
        List<String> removeUserIds = new ArrayList<>();
        List<String> addUserIds = new ArrayList<>();
        List<String> updateUserIds = new ArrayList<>();

        // 用户表中无数据时，全量新增
        if (CollectionUtil.isEmpty(existUserIds)) {
            addUserIds.addAll(authCenterUserIds);
        } else {
            for (String userId : authCenterUserIds) {
                // 认证中心存在，用户表中不存在，进行新增
                if (!existUserIds.contains(userId)) {
                    addUserIds.add(userId);
                }
            }
        }

        for (String existUserId : existUserIds) {
            // 认证中心已不存在，进行删除
            if (!authCenterUserIds.contains(existUserId)) {
                removeUserIds.add(existUserId);
            } else {
                // 若存在进行更新
                updateUserIds.add(existUserId);
            }
        }
        //新增
        if (CollectionUtil.isNotEmpty(addUserIds)) {
            List<User> addUsers = new ArrayList<>();
            addUserIds.forEach(userId -> {
                AuthCenterUser authCenterUser = authCenterUsersMap.get(userId);
                User user = User.builder()
                        .userId(authCenterUser.getId())
                        .userName(authCenterUser.getName())
                        .userNickname(authCenterUser.getNickname())
                        .userPassword(authCenterUser.getSecretKey())
                        .gerritUserName(authCenterUser.getGitName())
                        .gerritPassword(authCenterUser.getGitPassword())
                        .build();
                addUsers.add(user);
            });
            userRepository.addUsers(addUsers);
        }

        //修改
        if (CollectionUtil.isNotEmpty(addUserIds)) {
            List<User> modifyUsers = new ArrayList<>();
            updateUserIds.stream().forEach(userId -> {
                AuthCenterUser authCenterUser = authCenterUsersMap.get(userId);
                User user = User.builder()
                        .id(existUsersMap.get(userId).getId())
                        .userId(authCenterUser.getId())
                        .userName(authCenterUser.getName())
                        .userNickname(authCenterUser.getNickname())
                        .userPassword(authCenterUser.getSecretKey())
                        .build();
                modifyUsers.add(user);
            });
            userRepository.updateUsers(modifyUsers);
        }

        //删除
        if (CollectionUtil.isNotEmpty(removeUserIds)) {
            userRepository.deleteByUserIds(removeUserIds);
        }
    }


}
